﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.IO;
using Opennav.MapGenerator.Geometry;

namespace Opennav.MapGenerator.Map.Roads
{
    public class RoadJunction
    {
        public static byte HAS_RESTRICTIONS = 0x80;
        public static byte IS_ROUNDABOUD = 0x40;
        public static byte IS_TURNING_CIRCLE = 0x20;

        public static uint LAST_SEGMENT = 0x80000000;

        private List<RoadSegment> _segments = new List<RoadSegment>();
        private List<RoadRestriction> _restrictions = new List<RoadRestriction>();
        private int _offset = -1;

        public RoadJunction(Coordinate coordinate)
        {
            this.Coordinate = coordinate;
        }

        public int Offset
        {
            get
            {
                Debug.Assert(_offset >= 0);
                return _offset;
            }
            set
            {
                _offset = value;
            }
        }

        public bool IsRoundabout { get; set; }

        public bool IsTurningCircle { get; set; }

        public Coordinate Coordinate { get; set; }

        public IList<RoadSegment> Segments { get { return _segments; } }

        public IList<RoadRestriction> Restrictions { get { return _restrictions; } }

        public void Write(Stream stream)
        {
            BinaryWriter writer = new BinaryWriter(stream);

            Debug.Assert(Segments.Count > 0);

            byte flags = 0;
            if (Restrictions.Count > 0) flags |= HAS_RESTRICTIONS;
            if (IsRoundabout) flags |= IS_ROUNDABOUD;
            if (IsTurningCircle) flags |= IS_TURNING_CIRCLE;

            writer.Write(flags);

            writer.Write((byte)(Coordinate.Longitude & 0xff));
            writer.Write((short)(Coordinate.Longitude >> 8));

            writer.Write((byte)(Coordinate.Latitude & 0xff));
            writer.Write((short)(Coordinate.Latitude >> 8));

            for (int i = 0; i < Segments.Count; i++)
            {
                uint offset = (uint)Segments[i].Offset;
                if (i == Segments.Count - 1)
                    offset = offset | LAST_SEGMENT;
                writer.Write(offset);
            }
        }
    }
}
